Imports System
Imports System.ComponentModel
Imports NUnit.Framework
Imports ValidationFramework

Namespace BusinessBaseClasses
    Public Class NotifyValidatableBaseStringExample
#Region "Example"
        Public Class Person
            Inherits NotifyValidatableBase


            ' Fields
            Private _emailAddress As String
            Public Const EmailAddressMember As String = "EmailAddress"
            Private _firstName As String
            Public Const FirstNameMember As String = "FirstName"
            Private _lastName As String
            Public Const LastNameMember As String = "LastName"

            ' Methods
            Public Sub New()
                MyBase.New()
                PropertyValidationManager.ValidateAll()
            End Sub


            ' Properties
            <RequiredStringRule(), RegexValidatorAttribute("\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", _
                                             ErrorMessage:="Invalid email format."), LengthStringRule(50)> _
            Public Property EmailAddress() As String
                Get
                    Return _emailAddress
                End Get
                Set(ByVal value As String)
                    If (Not _emailAddress Is value) Then
                        _emailAddress = value
                        MyBase.NotifyAndValidate(EmailAddressMember)
                    End If
                End Set
            End Property

            <RequiredStringRule(), LengthStringRule(4)> _
            Public Property FirstName() As String
                Get
                    Return _firstName
                End Get
                Set(ByVal value As String)
                    If (Not _firstName Is value) Then
                        _firstName = value
                        MyBase.NotifyAndValidate(FirstNameMember)
                    End If
                End Set
            End Property

            <LengthStringRule(50, Minimum:=2), RequiredStringRule()> _
            Public Property LastName() As String
                Get
                    Return _lastName
                End Get
                Set(ByVal value As String)
                    If (Not _lastName Is value) Then
                        _lastName = value
                        MyBase.NotifyAndValidate(LastNameMember)
                    End If
                End Set
            End Property


        End Class


        <TestFixture()> _
        Public Class ExampleUsage


            ' Fields
            Private firstNameEventFired As Boolean

            ' Methods
            Private Sub person_PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
                ' Check that it is the property we are interested in
                If (e.PropertyName Is Person.FirstNameMember) Then
                    firstNameEventFired = True
                End If
            End Sub

            <Test()> _
            Public Sub RunEvent()
                Dim _person As New Person

                ' Attach to PropertyChanged so we are notified 
                AddHandler _person.PropertyChanged, New PropertyChangedEventHandler(AddressOf person_PropertyChanged)

                ' Set FirstName and hence firing the event
                _person.FirstName = "John"

                ' Since the event has fired the firstNameEventFired flag will be true;
                Assert.IsTrue(firstNameEventFired)
            End Sub

            <Test()> _
            Public Sub RunIsValid()
                Dim _person As New Person

                ' Initially not valid
                Assert.IsFalse(_person.IsValid)

                ' Set FirstName, LastName and EmailAddress
                _person.FirstName = "John"
                _person.LastName = "Smith"
                _person.EmailAddress = "John.Smith@email.com"

                ' It is now valid
                Assert.IsTrue(_person.IsValid)
            End Sub

            <Test()> _
            Public Sub RunSpecificProperty()
                Dim _person As New Person

                ' LastName initially has an ErrorMessage because it is invalid
                Dim lastNameErrorMessage As String = _
                        _person.Item(Person.LastNameMember)
                Assert.IsNotNull(lastNameErrorMessage)

                ' Set LastName and it will then have no ErrorMessage
                _person.LastName = "Smith"
                ' No need to call IsValid (to force a validation) because properties are validated
                ' during each set
                lastNameErrorMessage = _
                    _person.Item(Person.LastNameMember)
                Assert.IsEmpty(lastNameErrorMessage)
            End Sub

            <Test()> _
            Public Sub RunValidatorResultsInError()
                Dim _person As New Person
                ' Initially there should be 3 items in ValidatorResultsInError as only 3
                ' properties have required rules.
                Assert.AreEqual(3, _person.ValidatorResultsInError.Count)

                ' Set LastName to a value and count goes down to 2
                _person.LastName = "Smith"
                ' No need to call IsValid (to force a validation) because properties are 
                ' validated during each set
                Assert.AreEqual(2, _person.ValidatorResultsInError.Count)
            End Sub


        End Class
#End Region
    End Class
End Namespace